package com.moter.bigdata.task;

import com.moter.bigdata.entity.JobInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;


import java.util.Calendar;
import java.util.List;

@Component
public class JobInfoProcessor implements PageProcessor {
    //    private final String url="https://jobs.51job.com/chengdu-slq/117843832.html?s=01&t=0";

    /**
     * 解析界面
     *
     * @param page page
     */
    @Override
    public void process(Page page) {
        //解析页面，获取招聘信息想去的url地址
        //列表页是js解析的所有通过字符串操作获取
        String[] script = page.getHtml().toString()
                //获取js里面的数据
                .split("window.__SEARCH_RESULT__ = ");

        //如果获取的集合为空，则是详情页
        if (script.length > 1) {
//            System.out.println("这是列表页");
            //获取链接，并且加入队列
            String[] urls = script[1].split("</script> ")[0].split("job_href\":\"");

            for (int i = 1; i < urls.length; i++) {
                page.addTargetRequest(urls[i].split("\",")[0].replace("\\", ""));
            }
            //获取页数
            int totalPage = Integer.parseInt(page.getHtml().toString()
                    .split("total_page\":")[1]
                    .split(",")[0]
                    .replaceAll("\"", ""));
            for (int i = 2; i <= totalPage; i++) {
                page.addTargetRequest("https://search.51job.com/list/090200,000000,0000,00,9,99,java,2," + i + ".html");
            }
//            for (Request targetRequest : page.getTargetRequests()) {
//                System.out.println(targetRequest.getUrl());
//            }
        }
        //抓不到就是列表页
        else {
//            System.out.println("这是详情页");
            saveJobInfo(page);
        }
    }

    private final Site site = Site.me()
            //设置字符编码
            .setCharset("gbk")
            //设置超时时间
            .setTimeOut(10 * 1000)
            //设置重试的时间间隔
            .setRetrySleepTime(3000)
            //设置重试次数
            .setRetryTimes(3)
            .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36")
            .addHeader("Host", "jobs.51job.com");

    @Override
    public Site getSite() {
        return site;
    }

    public void saveJobInfo(Page page) {
        //创建招聘详情对象
        JobInfo jobInfo = new JobInfo();

        //解析页面
        Html html = page.getHtml();
        String[] str = html.xpath("/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/@title").toString().split(" ");
        //获取数据封装到对象中
        jobInfo.setCompanyName(html.xpath("/html/body/div[3]/div[2]/div[2]/div/div[1]/p[1]/a[1]/@title").toString());
        jobInfo.setCompanyAddr(str[0]);

        jobInfo.setUrl(page.getUrl().toString());
        jobInfo.setCompanyInfo(html.xpath("/html/body/div[3]/div[2]/div[3]/div[3]/div/text()").toString());
        jobInfo.setJobAddr(html.xpath("/html/body/div[3]/div[2]/div[3]/div[2]/div/p/text()").toString());
        jobInfo.setJobInfo(html.xpath("/html/body/div[3]/div[2]/div[3]/div[1]/div/p").all().toString());
        jobInfo.setJobName(html.xpath("/html/body/div[3]/div[2]/div[2]/div/div[1]/h1/@title").toString());
        Integer[] salary = getSalary(html.xpath("/html/body/div[3]/div[2]/div[2]/div/div[1]/strong/text()").toString());
        jobInfo.setSalaryMax(salary[0]);
        jobInfo.setSalaryMin(salary[1]);
        for (int i = str.length - 1; i >= 0; i--) {
            if (str[i].endsWith("发布")) {
                jobInfo.setTime(Calendar.getInstance().get(Calendar.YEAR) + "-" + str[i].replace("发布", ""));
                break;
            }
        }
        List<Selectable> nodes = html.xpath("/html/body/div[3]/div[2]/div[3]/div[1]/div/div[1]/p[2]/a").nodes();
        String keyword = "";
        for (int i = 0; i < nodes.size(); i++) {
            keyword += nodes.get(i).toString().split(">")[1].split("<")[0];
            if (i < nodes.size() - 1)
                keyword += ",";
        }
        jobInfo.setKeyword(keyword);
        //保存数据
        page.putField("jobInfo", jobInfo);
    }

    /**
     * 获得薪资最大和最小
     *
     * @param salary
     * @return
     */
    public static Integer[] getSalary(String salary) {
        try {
            if (salary.contains("天")) {
                String s = salary.split("元/")[0];
                return new Integer[]{Integer.parseInt(s) * 30, Integer.parseInt(s) * 30};
            }
            if (salary == null || "".equals(salary))
                return new Integer[]{-1, -1};
            String[] split = salary.split("-");
            double min = Double.parseDouble(split[0]);
            String[] split1 = split[1].split("万|千");

            double max = Double.parseDouble(split1[0]);
            String[] split2 = split1[1].split("/");
            if (salary.contains("万")) {
                min *= 10000;
                max *= 10000;
            } else {
                min *= 1000;
                max *= 1000;
            }
            if (split2[1].equals("年")) {
                min /= 12;
                max /= 12;
            }
            return new Integer[]{(int) min, (int) max};
        }catch (Exception e){
            e.printStackTrace();
            return new Integer[]{-1,-1};
        }
    }

    @Autowired
    private JobInfoPipeline jobInfoPipeline;

    /**
     * initialDelay任务启动后，等待xx执行方法
     * fixedDelay每间隔xx执行一次
     */
//    @Scheduled(initialDelay = 1000, fixedDelay = 100 * 10000000)
    @Scheduled(cron = "0 34 3 * * ?")
    public void processJava() {
        String url = "https://search.51job.com/list/090200,000000,0000,00,9,99,java,2,1.html";
        Spider spider = Spider.create(new JobInfoProcessor())
                //请求地址
                .addUrl(url)
                //设置去重 ： 布隆过滤器
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))
                //设置十个线程
                .thread(5)
                //执行
                .addPipeline(jobInfoPipeline);
        spider.run();
    }

    //    @Scheduled(initialDelay = 1000*60*60*, fixedDelay = 100 * 10000000)
    @Scheduled(cron = "0 20 5 * * ?")
    public void processPython() {
        String url = "https://search.51job.com/list/090200,000000,0000,00,9,99,python,2,1.html";
        Spider spider = Spider.create(new JobInfoProcessor())
                //请求地址
                .addUrl(url)
                //设置去重 ： 布隆过滤器
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))
                //设置十个线程
                .thread(5)
                //执行
                .addPipeline(jobInfoPipeline);
        spider.run();
    }

    //    @Scheduled(initialDelay = 1000, fixedDelay = 100 * 10000000)
    @Scheduled(cron = "0 50 6 * * ?")
    public void processCpp() {
        String url = "https://search.51job.com/list/090200,000000,0000,00,9,99,c++,2,1.html";
        Spider spider = Spider.create(new JobInfoProcessor())
                //请求地址
                .addUrl(url)
                //设置去重 ： 布隆过滤器
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))
                //设置十个线程
                .thread(5)
                //执行
                .addPipeline(jobInfoPipeline);
        spider.run();
    }

    //    @Scheduled(initialDelay = 1000, fixedDelay = 100 * 10000000)
    @Scheduled(cron = "0 10 8 * * ?")
    public void processGolang() {
        String url = "https://search.51job.com/list/090200,000000,0000,00,9,99,Go,2,1.html";
        Spider spider = Spider.create(new JobInfoProcessor())
                //请求地址
                .addUrl(url)
                //设置去重 ： 布隆过滤器
                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))
                //设置十个线程
                .thread(5)
                //执行
                .addPipeline(jobInfoPipeline);
        spider.run();
    }

    //    @Scheduled(cron = "0 10 8 * * ?")
//    public void processGolang() {
//        String url = "https://search.51job.com/list/090200,000000,0000,00,9,99,Go,2,1.html";
//        Spider spider = Spider.create(new JobInfoProcessor())
//                //请求地址
//                .addUrl(url)
//                //设置去重 ： 布隆过滤器
//                .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))
//                //设置十个线程
//                .thread(5)
//                //执行
//                .addPipeline(jobInfoPipeline);
//        spider.run();
//    }
    public static void main(String[] args) {
        Integer[] salary = getSalary("300元/天");
        System.out.println(salary[0] + " " + salary[1]);
    }

}
